package com.h3c.ptability.utils;

import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.h3c.ptability.support.PageQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author :h24002
 * @date :2022/10/27 14:28
 * @description :MybatisUtils
 */
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MybatisUtils {
    public static final String RIGHT_COLUMN_REG = "^[A-Za-z0-9_-]+$";

    /**
     * 设置排序字段（默认按照第一个字段升序）
     *
     * @param page     Page对象
     * @param sortList 排序字段List
     * @author z22968
     * @date 2022-03-21 11:32
     */
    public static void setOrderBy(Page page, List<OrderItem> sortList) {
        // 设置默认排序(sqlserver 的 offset...fetch分页必须添加order by)
        if (CollectionUtils.isEmpty(sortList)) {
            sortList = new ArrayList<>();
            sortList.add(OrderItem.asc("1"));
        }
        checkColumnList(sortList);
        page.setOrders(sortList);
    }


    /**
     * 设置单个字段升序
     *
     * @param page   page
     * @param column 排序字段
     * @author z22968
     * @date 2022-07-22 14:30
     */
    public static <T, R> void setOrderByAsc(Page page, SFunction<T, R> column) {
        setOrderBy(page, column, true);
    }

    /**
     * 设置单个字段降序
     *
     * @param page   page
     * @param column 排序字段
     * @author z22968
     * @date 2022-07-22 14:30
     */
    public static <T, R> void setOrderByDesc(Page page, SFunction<T, R> column) {
        setOrderBy(page, column, false);
    }

    /**
     * 设置单个排序
     *
     * @param page   page
     * @param column 排序字段
     * @param asc    排序方式
     * @author z22968
     * @date 2022-07-22 14:30
     */
    public static <T, R> void setOrderBy(Page page, SFunction<T, R> column, boolean asc) {
        // 设置默认排序(sqlserver 的 offset...fetch分页必须添加order by)
        List<OrderItem> sortList = new ArrayList<>();
        String columnName = getColumnName(column);
        checkColumn(columnName);
        if (asc) {
            sortList.add(OrderItem.asc(columnName));
        } else {
            sortList.add(OrderItem.desc(columnName));
        }
        page.setOrders(sortList);
    }

    /**
     * 转化IPage
     *
     * @param oldPage 旧IPage
     * @param records 需要放入的数据
     * @return com.baomidou.mybatisplus.core.metadata.IPage<E>
     * @author z22968
     * @date 2022-03-30 15:24
     */
    public static <T, E> IPage<E> changeIPage(IPage<T> oldPage, List<E> records) {
        Page<E> newPage = new Page<>(oldPage.getCurrent(), oldPage.getSize(), oldPage.getTotal());
        newPage.setPages(oldPage.getPages());
        if (!CollectionUtils.isEmpty(records)) {
            newPage.setRecords(records);
        }
        return newPage;
    }

    /**
     * 转化IPage
     *
     * @param pageQuery 查询时的参数
     * @param records   需要放入的数据
     * @param total     数据总数
     * @return com.baomidou.mybatisplus.core.metadata.IPage<E>
     * @author z22968
     * @date 2022-03-30 15:24
     */
    public static <T, E> IPage<E> changeIPage(PageQuery<T> pageQuery, List<E> records, long total) {
        Page<E> newPage = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize(), total);
        newPage.setPages(0);
        if (!CollectionUtils.isEmpty(records)) {
            newPage.setRecords(records);
        }
        return newPage;
    }

    /**
     * lambda转@TableField中的值, 没有则使用属性名
     *
     * @param column lambda表达式
     * @return java.lang.String
     * @author z22968
     * @date 2022-07-22 16:06
     */
    public static <T> String getColumnName(SFunction<T, ?> column) {
        return FieldUtils.getFieldName(column, true);
    }

    /**
     * 检查排序集合是否合法
     *
     * @param sortList 排序列列表
     * @author z22968
     * @date 2022-09-02 14:56
     */
    private static void checkColumnList(List<OrderItem> sortList) {
        for (OrderItem orderItem : sortList) {
            String column = orderItem.getColumn();
            checkColumn(column);
        }
    }

    /**
     * 判断是否为合法列名
     *
     * @param column 列名
     * @author z22968
     * @date 2022-09-02 14:54
     */
    public static void checkColumn(String column) {
        if (!ReUtil.isMatch(RIGHT_COLUMN_REG, column)) {
            throw new AppBusinessException("排序参数中含有非法的列名: " + column);
        }
    }
}

